﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Drawing.Drawing2D;

namespace Djs.Tools.Tresor.Gui
{
    #region class KeyPanel
    public class KeyPanel : GControl
    {
        #region Konstrukce a privátní život
        public KeyPanel()
        {
            this.ResizeRedraw = true;
            this._Tpb = new TransparentPictureBox();
            this._Tpb.Image = Properties.Resources.SecureKey;
            this._Tpb.Transparency = 0.33f;
        }
        protected TransparentPictureBox _Tpb;
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            this._Tpb.Bounds = this.ClientRectangle;
            this.Draw();
        }
        protected override void OnPaintToBuffer(object sender, PaintEventArgs e)
        {
            base.OnPaintToBuffer(sender, e);
            e.Graphics.ResetClip();
            this._Tpb.Draw(e.Graphics);
        }
        #endregion
        #region Public property
        /// <summary>
        /// Úroveň složitosti klíče
        /// </summary>
        [DefaultValue(0.65f)]
        public float KeyLevel { get { return this._Tpb.Transparency; } set { this._Tpb.Transparency = value; this.Draw(); } }

        public Image KeyImage { get { return this._Tpb.Image; } set { this._Tpb.Image = value; this.Draw(); } }

        #endregion
    }
    #endregion
    #region class TransparentPictureBox
    public class TransparentPictureBox
    {
        public TransparentPictureBox()
        {
            this._Transparency = 0.65f;
        }
        public Image Image { get { return this._Image; } set { this._Image = value; this.Draw(); } } private Image _Image;
        /// <summary>
        /// Průhlednost
        /// </summary>
        [DefaultValue(0.65f)]
        public float Transparency { get { return this._Transparency; } set { this._Transparency = value; this.Draw(); } } private float _Transparency;

        public Control Parent { get { return this._Parent; } set { this.ParentLeave(); this._Parent = value; this.ParentLink(); this.Draw(); } } private Control _Parent;
        public Rectangle Bounds { get { return this._Bounds; } set { this._Bounds = value; this.Draw(); } } private Rectangle _Bounds;

        protected void ParentLink()
        {
            if (this._Parent != null)
                this._Parent.Paint += new PaintEventHandler(_Parent_Paint);
        }
        protected void ParentLeave()
        {
            if (this._Parent != null)
                this._Parent.Paint -= new PaintEventHandler(_Parent_Paint);
        }

        void _Parent_Paint(object sender, PaintEventArgs e)
        {
            this.Draw(e.Graphics);
        }
        public void Draw()
        {
            if (this._Parent == null) return;
            if (this._Image == null) return;
            if (this._Transparency < 0f) return;

            this._Parent.Invalidate();
        }
        public void Draw(Graphics graphics)
        {
            if (this._Image == null) return;
            if (this._Transparency < 0f) return;

            RectangleF bounds = this._Bounds;
            if (bounds.Width < 10 || bounds.Height < 10) return;

            SizeF destSize = new SizeF(bounds.Width, bounds.Height);

            Image image = this._Image;
            SizeF imageSize = image.Size;
            float imageRatio = imageSize.Width / imageSize.Height;

            float destRatio = (destSize.Width - 6f) / (destSize.Height - 6f);
            if (destRatio < imageRatio)
                // Cíl je užší než image, image využije celou šířku dest a vycentruje se na ose Y:
                destSize.Height = destSize.Width / imageRatio;
            else
                // Cíl je širší než image, image využije celou výšku dest a vycentruje se na ose X:
                destSize.Width = destSize.Height * imageRatio;

            // Určím pozici destRect = destSize vystředěná v this:
            PointF destPoint = new PointF(bounds.X + (bounds.Width - destSize.Width) / 2f, bounds.Y + (bounds.Height - destSize.Height) / 2f);
            Rectangle destRect = Rectangle.Round(new RectangleF(destPoint, destSize));

            System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix();
            cm.Matrix33 = (this._Transparency < 0f ? 0f : (this._Transparency > 1f ? 1f : this._Transparency));

            System.Drawing.Imaging.ImageAttributes im = new System.Drawing.Imaging.ImageAttributes();
            im.SetColorMatrix(cm);

            graphics.DrawImage(image, destRect, 0f, 0f, imageSize.Width, imageSize.Height, GraphicsUnit.Pixel, im);
        }

    }
    #endregion
    #region KeyInfo
    public class KeyInfo
    {
        public KeyInfo()
        {
        }
        /// <summary>
        /// Síla klíče 0 - 1
        /// </summary>
        [DefaultValue(0.65f)]
        public float Strong { get { return (this._Strong < 0f ? 0f : (this._Strong > 1f ? 1f : this._Strong)); } set { this._Strong = value; this.Draw(); } } private float _Strong;

        public Control Parent { get { return this._Parent; } set { this.ParentLeave(); this._Parent = value; this.ParentLink(); this.Draw(); } } private Control _Parent;
        public Rectangle Bounds { get { return this._Bounds; } set { this._Bounds = value; this.Draw(); } } private Rectangle _Bounds;
        public Font Font { get { return this._Font; } set { this._Font = value; this.Draw(); } } private Font _Font;
        public Color ForeColor { get { return this._ForeColor; } set { this._ForeColor = value; this.Draw(); } } private Color _ForeColor;

        protected void ParentLink()
        {
            if (this._Parent != null)
                this._Parent.Paint += new PaintEventHandler(_Parent_Paint);
        }
        protected void ParentLeave()
        {
            if (this._Parent != null)
                this._Parent.Paint -= new PaintEventHandler(_Parent_Paint);
        }

        private void _Parent_Paint(object sender, PaintEventArgs e)
        {
            this.Draw(e.Graphics);
        }
        public void Draw()
        {
            if (this._Parent == null) return;

            this._Parent.Invalidate();
        }
        public void Draw(Graphics graphics)
        {
            Rectangle bounds1 = this._Bounds;
            // System.Windows.Forms.TextBoxRenderer.DrawTextBox(graphics, bounds, System.Windows.Forms.VisualStyles.TextBoxState.Normal);
            System.Windows.Forms.ProgressBarRenderer.DrawHorizontalBar(graphics, bounds1);

            float strong = this.Strong;
            int width = (int)(strong * (float)(bounds1.Width - 5));
            Rectangle bounds2 = new Rectangle(bounds1.X + 3, bounds1.Y + 2, width, bounds1.Height - 4);
            System.Windows.Forms.ProgressBarRenderer.DrawHorizontalChunks(graphics, bounds2);

            string text = "Síla klíče: " + this.Text;
            SizeF textSize = graphics.MeasureString(text, this._Font);
            Rectangle bounds3 = new Rectangle(bounds1.X + 3, bounds1.Y + ((bounds1.Height - (int)textSize.Height) / 2) + 1, bounds1.Width - 6, bounds1.Height - 4);
            System.Windows.Forms.TextRenderer.DrawText(graphics, text, this._Font, bounds3, this._ForeColor, TextFormatFlags.HorizontalCenter);
        }
        public string Text
        {
            get
            {
                float strong = this.Strong;
                if (strong < 0f) return "vůbec žádná";
                if (strong == 0f) return "žádná";
                if (strong < 0.04f) return "slabý jako dech";
                if (strong < 0.07f) return "slabý jako čajíček";
                if (strong < 0.10f) return "slabý";
                if (strong < 0.3f) return "střední";
                if (strong < 0.5f) return "skoro dobrý";
                if (strong < 0.7f) return "dobrý";
                if (strong < 0.8f) return "dost dobrý";
                if (strong < 0.9f) return "silný";
                if (strong < 1.0f) return "silnější než NSA";
                return "bez šance na prolomení";
            }
        }
    }
    #endregion
}
